package com.gitee.chili.leisure.message;

import com.gitee.chili.leisure.RoomManager;
import com.gitee.chili.leisure.core.AbstractDefaultMessage;
import com.gitee.chili.leisure.core.Packet;
import com.gitee.chili.leisure.enums.State;
import com.gitee.chili.leisure.game.RoomDetail;
import com.gitee.chili.leisure.model.HallModel;
import com.gitee.chili.leisure.model.MessageCmdEnum;
import com.google.protobuf.InvalidProtocolBufferException;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.concurrent.atomic.LongAdder;

/**
 * Ready
 *
 * @author week solider
 * @since 2020.09.08
 */
@Slf4j
public class Ready extends AbstractDefaultMessage {

    private int seatNum;

    private boolean needStart;

    public Ready(Packet packet, Channel channel) {
        super(packet, channel);
    }

    @Override
    protected void decoder(byte[] body) throws InvalidProtocolBufferException {
        HallModel.ReadyGameCmd readyGame = HallModel.ReadyGameCmd.parseFrom(body);

        if (Objects.isNull(readyGame)) {
            log.error("准备异常");
            return;
        }

        Long memberId = getMemberId();
        Long roomNum = getRoomNum();

        RoomDetail roomDetail = RoomManager.obtain(roomNum);

        LongAdder incr = new LongAdder();
        roomDetail.getPlayers().forEach(p -> {
            if (p.getUserId().equals(memberId)) {
                p.setStatus(State.readying);
                seatNum = p.getPosition();
            }
            if (p.getStatus().equals(State.readying))
                incr.increment();
        });
        needStart = incr.sum() >= roomDetail.getPeopleNum();
    }

    @Override
    public Packet parseBody() {
        HallModel.NotifyMemberReadyGameResult.Builder builder = HallModel.NotifyMemberReadyGameResult.newBuilder();
        builder.setSeatNum(seatNum);
        return Packet.newPacket(MessageCmdEnum.Command.NOTIFY_MEMBER_READY_GAME, builder.build().toByteArray());
    }

    /**
     * 是否需要开始游戏
     */
    public boolean isNeedStart() {
        return needStart;
    }
}
